﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Windows;

namespace XMM.Objects
{
    public class Series : Object
    {
        /// <summary>
        /// This Series' Database-Record ID.
        /// </summary>
        public int SeriesID { get; set; }

        /// <summary>
        /// Name or Title of this Series.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Plot or Description.
        /// </summary>
        public string Plot { get; set; }

        /// <summary>
        /// Actors.
        /// </summary>
        public string Cast { get; set; }

        /// <summary>
        /// Director.
        /// </summary>
        public string Director { get; set; }

        /// <summary>
        /// Genre Database-Record ID.
        /// </summary>
        public int GenreID { get; set; }

        /// <summary>
        /// Tvdb-Database-ID of this series.
        /// </summary>
        public int TvdbID { get; set; }

        /// <summary>
        /// List of all Seasons corresponding to this series.
        /// </summary>
        public List<SeriesSeason> Seasons { get; set; }

        /// <summary>
        /// Initialize a blank Series-Object.
        /// </summary>
        public Series()
        {
            blankValues();
        }

        public Series(int iSeriesID)
        {
            Load(iSeriesID);
        }

        public override string ToString()
        {
            return Name;
        }

        public void blankValues()
        {
            SeriesID = 0;
            Name = String.Empty;
            Plot = String.Empty;
            Cast = String.Empty;
            Director = String.Empty;
            GenreID = 0;
            TvdbID = 0;
            Seasons = new List<SeriesSeason>();
        }

        public static bool Delete(int iSeriesID)
        {
            if (iSeriesID != 0)
            {
                Objects.Series oShow = new Series(iSeriesID);
                foreach (Objects.SeriesSeason oSeason in oShow.Seasons)
                {
                    if (oSeason.Delete() == false)
                    {
                        MessageBox.Show("\"" + oShow.Name + "\", Staffel " + oSeason.Number.ToString() + " konnte nicht gelöscht werden!", "Fehler beim Löschen", MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }
                }

                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    t_series vSeries = (from series in dbConnection.t_series where series.ID == iSeriesID select series).Single();

                    if (vSeries != null && vSeries.ID > 0)
                    {
                        dbConnection.t_series.DeleteOnSubmit(vSeries);
                        dbConnection.SubmitChanges();

                        return true;
                    }
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Löschen der Serie: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return false;
        }

        public bool Delete()
        {
            return Objects.Series.Delete(SeriesID);
        }

        public bool SaveNew()
        {
            if (Name != String.Empty)
            {
                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    t_series vSeries = new t_series();
                    vSeries.Name = Name;
                    vSeries.Director = Director;
                    vSeries.Plot = Plot;
                    vSeries.Cast = Cast;
                    vSeries.GenreID = GenreID;
                    vSeries.TvdbID = TvdbID;

                    dbConnection.t_series.InsertOnSubmit(vSeries);
                    dbConnection.SubmitChanges();

                    return true;
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Speichern der Serie \"" + Name + "\": " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                MessageBox.Show("Bitte geben Sie zumindest den Titel ein!", "Kein Titel, keine Eingabe...", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }

            return false;
        }

        public bool Load(int iSeriesID)
        {
            blankValues();

            if (iSeriesID != 0)
            {
                try
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    var vSeries = (from series in dbConnection.t_series where series.ID == iSeriesID select series).Single();

                    if (vSeries != null && vSeries.ID != 0)
                    {
                        SeriesID = vSeries.ID;
                        Name = vSeries.Name;

                        if (vSeries.Plot != null)
                            Plot = vSeries.Plot;

                        if (vSeries.Cast != null)
                            Cast = vSeries.Cast;

                        if (vSeries.Director != null)
                            Director = vSeries.Director;

                        GenreID = vSeries.GenreID;

                        TvdbID = (int)vSeries.TvdbID;

                        Seasons = getSeriesSeasons(SeriesID);

                        return true;
                    }
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Laden der Serie '" + iSeriesID.ToString() + "': " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                MessageBox.Show("Bitte wählen Sie eine gültige Serie!", "Serie ungültig", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }

            return false;
        }

        public static string getTitle(int iSeriesID)
        {
            string sTitle = String.Empty;

            Series oSeries = new Series(iSeriesID);
            sTitle = oSeries.Name;

            return sTitle;
        }

        /// <summary>
        /// Get all Seasons for a given Series-Database-ID.
        /// </summary>
        /// <param name="iTargetSeasonID">(int) Target-Season ID</param>
        /// <returns>[List(SeriesEpisode)] List of Episodes assignes to the selected SeasonID.</returns>
        public static List<SeriesSeason> getSeriesSeasons(int iTargetSeriesID)
        {
            List<SeriesSeason> lSeasons = new List<SeriesSeason>();

            try
            {
                if (iTargetSeriesID != 0)
                {
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    var vSeasons = from seasons in dbConnection.t_series_seasons where seasons.SeriesID == iTargetSeriesID orderby seasons.Number ascending select seasons.ID;

                    if (vSeasons != null && vSeasons.Count() > 0)
                    {
                        foreach (int iSeasonID in vSeasons)
                        {
                            SeriesSeason oSeason = new SeriesSeason(iSeasonID);
                            if (oSeason != null && oSeason.SeasonID != 0)
                                lSeasons.Add(oSeason);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Die angegebene Staffel konnte nicht in der Datenbank gefunden werden!", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            catch (SqlException ex)
            {
                MessageBox.Show("Fehler beim Abrufen der Episoden aus \"[SERIE]\", Staffel \"[SEASON]\": " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return lSeasons;
        }

        public static List<Series> getAllSeries()
        {
            List<Series> lSeries = new List<Series>();

            try
            {
                XMMDBDataContext dbConnection = new XMMDBDataContext();

                var vSeries = from series in dbConnection.t_series orderby series.Name select series.ID;

                if (vSeries != null && vSeries.Count() > 0)
                {
                    foreach (int iSeriesID in vSeries)
                    {
                        Series oSeries = new Series(iSeriesID);
                        if (oSeries != null && oSeries.SeriesID != 0)
                            lSeries.Add(oSeries);
                    }
                }
            }
            catch (SqlException ex)
            {
                MessageBox.Show("Fehler beim Abrufen der Serien: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return lSeries;
        }

        public static bool CheckExistance(string SeriesName)
        {
            if (SeriesName != String.Empty)
            {
                XMMDBDataContext dbConnection = new XMMDBDataContext();

                try
                {
                    var vSeries = from series in dbConnection.t_series select series.Name;

                    if (vSeries != null && vSeries.Count() > 0)
                    {
                        foreach (string sSeries in vSeries)
                        {
                            if (sSeries.ToUpper() == SeriesName.ToUpper())
                            {
                                return true;
                            }
                        }
                    }
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Fehler beim Prüfen der Existenz von \"" + SeriesName + "\": " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return false;
        }

        /// <summary>
        /// Get the last created Series object from database.
        /// </summary>
        /// <returns>(Objects.Series) Latest created Series-Object.</returns>
        public static Series getLatestSeries()
        {
            Series oLatestSeries = new Series();

            XMMDBDataContext dbConnection = new XMMDBDataContext();

            try
            {
                var vSeries = (from series in dbConnection.t_series select series.ID).Max();

                if (vSeries != null & vSeries > 0)
                {
                    oLatestSeries = new Series(vSeries);
                }
            }
            catch (SqlException ex)
            {
                MessageBox.Show("Fehler beim Abrufen der soeben erstellten Serie: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return oLatestSeries;
        }

        public List<Objects.SeriesEpisode> GetUnseen(int iAudienceID)
        {
            List<Objects.SeriesEpisode> lUnseenEpisodes = new List<SeriesEpisode>();

            foreach (Objects.SeriesSeason oSeason in Seasons)
            {
                foreach (Objects.SeriesEpisode oEpisode in oSeason.Episodes)
                {
                    if (oEpisode.SeenBy(iAudienceID) == false)
                    {
                        lUnseenEpisodes.Add(oEpisode);
                    }
                }
            }

            return lUnseenEpisodes;
        }
    }
}
